// -*-mode:c++; coding:utf-8-*-

#ifndef _XBASE_LOGGER_HPP_
#define _XBASE_LOGGER_HPP_


#define THE_XBASE_LOGGER_NAME "xbase"

// see ref: http://www.delorie.com/gnu/docs/gcc/gcc_78.html
// 
// __PRETTY_FUNCTION__ - 完整函数签名及作用域
// __FUNCTION__ - 只有函数名称

//#define APPEND_FUNCTION(MSG) MSG << " [" << __PRETTY_FUNCTION__ << "]"
#define APPEND_FUNCTION(MSG) MSG << " [" << __FUNCTION__ << "]"
//#define APPEND_FUNCTION(MSG) MSG

// 提供方便的日志记录
#define LOG(TYPE,MSG) LOG_##TYPE(the_xbase_logger, APPEND_FUNCTION(MSG));

#ifdef _SHOW_DETAIL_
#	define LOG_DETAIL(a,b) LOG_TRACE(a,b)
#else
#	define LOG_DETAIL(a,b)
#endif	// _SHOW_DETAIL_

#define LOG_TRACE(a,b) LOG4CPLUS_TRACE(a,b)
#define LOG_DEBUG(a,b) LOG4CPLUS_DEBUG(a,b)
#define LOG_INFO(a,b)  LOG4CPLUS_INFO(a,b)
#define LOG_WARN(a,b)  LOG4CPLUS_WARN(a,b)
#define LOG_ERROR(a,b) LOG4CPLUS_ERROR(a,b)
#define LOG_FATAL(a,b) LOG4CPLUS_FATAL(a,b)

#define LOG_CONFIG(conf) LOG4CPLUS_DO_CONFIG(conf)


// 在调试选项未关闭的情况下，仍打开日志选项
#ifndef LOGGER
#	ifndef NDEBUG
#		define LOGGER
#	endif
#endif


#ifdef LOGGER
#	include <log4cplus/logger.h>
#	include <log4cplus/configurator.h>
#	include <log4cplus/tstring.h>

#define DECL_LOGGER(logger) static log4cplus::Logger logger;
#define IMPL_LOGGER(classname, logger) log4cplus::Logger classname::logger = log4cplus::Logger::getInstance(#classname);
#define TEMPLATE_IMPL_LOGGER(classname, logger) template<class T> log4cplus::Logger classname<T>::logger = log4cplus::Logger::getInstance(#classname);

#define LOG4CPLUS_DO_CONFIG(conf) log4cplus::PropertyConfigurator::doConfigure(conf)

extern log4cplus::Logger the_xbase_logger;

#define LOG_IF(pred, level, msg) do {		\
		if (pred) {			\
			LOG(level, msg);	\
		}				\
	} while(false)

#define LOG_IF_ELSE(pred, level1, msg1, level2, msg2) do {	\
		if (pred) {					\
			LOG(level1, msg1);			\
		} else {					\
			LOG(level2, msg2);			\
		}						\
	} while(false)

#define LOG_ENV(x) x

struct __debug_log_utility_function_trace
{
	__debug_log_utility_function_trace(const std::string &name)
		: m_name(name) {
		LOG(TRACE, m_name << " in");
	}
	~__debug_log_utility_function_trace() {
		LOG(TRACE, m_name << " out");
	}
	const std::string m_name;
};
#define TRACE(fun_name) __debug_log_utility_function_trace __debug_function_trace__(fun_name)

#else
#define _LOG4CPLUS_LOGGING_MACROS_HEADER_
#define LOG4CPLUS_TRACE(a,b)
#define LOG4CPLUS_DEBUG(a,b)
#define LOG4CPLUS_INFO(a,b)
#define LOG4CPLUS_WARN(a,b)
#define LOG4CPLUS_ERROR(a,b)
#define LOG4CPLUS_FATAL(a,b)

#define LOG_IF(pred, level, msg)
#define LOG_IF_ELSE(pred, level1, msg1, level2, msg2)

#define LOG_ENV(x)

#define DECL_LOGGER(logger)
#define IMPL_LOGGER(classname, logger)
#define TEMPLATE_IMPL_LOGGER(classname, logger)

#define LOG4CPLUS_DO_CONFIG(conf)

#define LOG4CPLUS_STRING_TO_TSTRING(string)

#define TRACE(fun_name) 

#endif

#endif	// _XBASE_LOGGER_HPP_
